package com.magicmovie.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.magicmovie.entity.Customer;
import com.magicmovie.mapper.CustomerMapper;
import com.magicmovie.service.CustomerService;
import com.magicmovie.utils.QueryFilters;
import com.magicmovie.utils.TokenGenerator;
import com.magicmovie.utils.data.PageModel;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Map;

@Service
public class CustomerServiceImpl implements CustomerService {
    @Autowired
    private CustomerMapper customerMapper;

    @Override
    public Customer findByUsername(String username) {
        return customerMapper.findByUsername(username);
    }

    @Override
    public Customer getByPrimaryKey(Integer id) {
        return customerMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional(readOnly = false)
    public void register(String username, String password) {
        Customer customer = new Customer();
        customer.setUsername(username);
        String salt = RandomStringUtils.randomAlphanumeric(20);
        customer.setSalt(salt);
        customer.setPassword(new Sha256Hash(password,salt).toHex());

        customerMapper.insert(customer);
    }

    @Override
    @Transactional(readOnly = false)
    public String createToken(@RequestBody Customer customer) throws NoSuchAlgorithmException {
        String token = null;
        while (true) {
            token = TokenGenerator.generateValue();
            Customer c = customerMapper.findByToken(token);
            if (c == null) break;
        }
        customer.setToken(token);
        customer.setLastLoginTime(new Date());
        customerMapper.updateByPrimaryKeySelective(customer);
        return token;
    }

    @Override
    public Customer findByToken(String token) {
        return customerMapper.findByToken(token);
    }

    @Override
    @Transactional(readOnly = false)
    public void logout(@RequestBody Customer customer) throws NoSuchAlgorithmException {
        String token = null;
        while (true) {
            token = TokenGenerator.generateValue();
            Customer c = customerMapper.findByToken(token);
            if (c == null) break;
        }
        customer.setToken(token);
        customerMapper.updateByPrimaryKeySelective(customer);
    }

    @Override
    @Transactional(readOnly = false)
    public void updateByPrimaryKeySelective(@RequestBody Customer customer) {
        customerMapper.updateByPrimaryKeySelective(customer);
    }

    @Override
    public PageModel getByFilter(@RequestBody QueryFilters filters) {
        PageHelper.startPage(filters.getPageNo(), filters.getPageSize());
        Page<Map<String, Object>> maps = customerMapper.getByFilter(filters);

        PageModel pageModel = new PageModel<>();
        pageModel.setTotalRecord(Math.toIntExact(maps.getTotal()));
        pageModel.setPageNo(maps.getPageNum());
        pageModel.setPageSize(maps.getPageSize());
        pageModel.setResults(maps.getResult());
        pageModel.setTotalPage(maps.getPages());
        return pageModel;
    }

    @Override
    public Integer queryCount() {
        return customerMapper.queryCount();
    }

}
